/* 
 * Copyright (c) 2006 - 2014 QIU ZHONG HUAI <huai2011@163.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:

 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    "This product includes CC software, freely available from
 *    <https://github.com/huai2001/CC/>".
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _C_CC_CONFIG_COMPILER_H_INCLUDED_
#define _C_CC_CONFIG_COMPILER_H_INCLUDED_
    
/* INTRIN_COMPILER_NAME.*/
#define CC_MACTOSTR(x) #x
#define CC_MACROVALUESTR(x) CC_MACTOSTR(x)

/* Define compiler */
#if defined(__GNUC__)
    /* GNU C++ */
    #define CC_GCC __GNUC__
    /* Macro for defining function name, file name, and line number */
    #define CC_SI_CM_FUNC __func__

    #if __GNUC__ >= 4
        #define CC_COMPILER_VERSION 4.0
    #elif __GNUC__ >= 3
        #define CC_COMPILER_VERSION 3.0
    #else
        #error Unknown compiler.
    #endif

    #if defined (__GNUC__) && __GNUC__ < 4
        /* Added support for GCC-EMX <v4.x */
        /* this is needed for XFree86/OS2 developement */
        /* F. Ambacher(anakor@snafu.de) 05.2008 */
        #ifndef CC_CALL
            #define CC_CALL _cdecl
        #endif
    #else
        /* On other compilers on OS/2, we use the _System calling convention */
        /* to be compatible with every compiler */
        #ifndef CC_CALL
            #define CC_CALL /*_System*/
        #endif
    #endif

    #ifdef CC_SHARED_LIBRARY
        #ifdef CC_ANDROID
            #define CC_DECLSPEC_ATTR __attribute__ ((visibility ("default")))
        #else
            /* Added support for GCC-EMX <v4.x */
            /* this is needed for XFree86/OS2 developement */
            /* F. Ambacher(anakor@snafu.de) 05.2008 */
            #if __GNUC__ >= 4
                #define CC_DECLSPEC_ATTR __attribute__ ((visibility("default")))
            #elif __GNUC__ < 4
                #define CC_DECLSPEC_ATTR __declspec(export)
            #endif
        #endif
    #else
        #define CC_DECLSPEC_ATTR
    #endif

    /* ConceptGCC compiler:
    //   http://www.generic-programming.org/software/ConceptGCC/
    */
    #ifdef __GXX_CONCEPTS__
        #define CC_COMPILER_NAME "ConceptGCC"
    #elif defined(__CYGWIN__)
        #define CC_COMPILER_NAME "GCC(Cygmin) " 
    #elif defined(__MINGW32__)
        #define CC_COMPILER_NAME "GCC(MinGW) "
    #else
        #define CC_COMPILER_NAME "GCC "
    #endif// #  if defined(__CYGWIN__)
    
#elif defined(_MSC_VER)
    /* Microsoft Visual C++
    //
    // Must remain the last #elif since some other vendors (Metrowerks, for example)
    // also #define _MSC_VER
    // Compiler version defines: VC6.0 : 1200, VC7.0 : 1300, VC7.1 : 1310, VC8.0 : 1400
    */
    #define CC_COMPILER_NAME "Microsoft VC++"
    
    /* Macro for defining function name, file name, and line number */
    #if _MSC_VER >= 1300
        #define CC_SI_CM_FUNC __FUNCDNAME__
    #else
        #define CC_SI_CM_FUNC __FUNCTION__
    #endif

    #ifndef _CRT_SECURE_NO_DEPRECATE
        #pragma warning(disable: 4996)
    #endif

    #pragma warning(disable: 4099)
    #pragma warning(disable: 4819)

    #if _MSC_VER >= 1500
        #ifndef _CRT_SECURE_NO_WARNINGS
            #define _CRT_SECURE_NO_WARNINGS
        #endif
    #endif
    
    #if _MSC_VER >= 1900
        #ifndef _WINSOCK_DEPRECATED_NO_WARNINGS
            #define _WINSOCK_DEPRECATED_NO_WARNINGS
        #endif
    #endif

    #if _MSC_VER >= 1900 /*VS 2015*/
        #define CC_COMPILER_VERSION 14.0
    #elif _MSC_VER >= 1700/*VS 2012*/
        #define CC_COMPILER_VERSION 11.0
    #elif _MSC_VER >= 1600/*VS 2010*/
        #define CC_COMPILER_VERSION 10.0
        #pragma warning(disable: 4996)
    #elif _MSC_VER >= 1400/*VS 2005*/
        #define CC_COMPILER_VERSION 8.0
        #pragma warning(disable: 4996)
    #elif _MSC_VER >= 1310/*VS 2003*/
        #define CC_COMPILER_VERSION 7.1
    #elif _MSC_VER >= 1300/*VS 2003*/
        #define CC_COMPILER_VERSION 7.0
    #elif _MSC_VER >= 1200/*VS 6.0*/
        #define CC_COMPILER_VERSION 6.0
    #elif defined(_MSC_FULL_VER)// #  if defined(_MSC_FULL_VER)
        #define CC_COMPILER_VERSION _MSC_FULL_VER
    #else
        #error Unknown compiler.
    #endif

    #ifdef CC_SHARED_LIBRARY
        #define CC_DECLSPEC_ATTR __declspec(dllexport)
        //#define CC_DECLSPEC_ATTR __declspec(dllimport)
    #else
        #define CC_DECLSPEC_ATTR
    #endif

    /* close windows.h min/max */
    #define NOMINMAX
    
#elif defined(__ICL) /* Intel C++*/
    #define CC_ICL __ICL

    /* Macro for defining function name, file name, and line number */
    #define CC_SI_CM_FUNC __FUNCDNAME__

    #ifndef CC_CALL
        #define CC_CALL __stdcall //_cdecl
    #endif

    #ifdef CC_SHARED_LIBRARY
        #define CC_DECLSPEC_ATTR
    #else
        #define CC_DECLSPEC_ATTR
    #endif

    #if defined(__VERSION__)
        #define CC_COMPILER_NAME "Intel C++"
    #elif defined(__INTEL_COMPILER_BUILD_DATE)
        #define CC_COMPILER_NAME "Intel C++"
    #endif    // #  if defined(__VERSION__)

    #define CC_COMPILER_NAME "Intel C++"
    #define CC_COMPILER_VERSION __VERSION__
#else
    #error unknown compiler
#endif /*end Define compiler*/


#endif        /* _C_CC_CONFIG_COMPILER_H_INCLUDED_*/
